// 实现这个项目的构建任务
const gulp = require("gulp")
const del = require("del")
const browserSync = require("browser-sync")
const { src, dest, parallel, series, watch } = require("gulp")
const loadPlugins = require("gulp-load-plugins")
// 路径抽象化
const cwd = process.cwd()
let config =  {
  build: {
    src: "src",
    temp: "temp",
    public: "public",
    dist: "dist",
    paths: {
      styles: "assets/styles/*.scss",
      script: "assets/scripts/*.js",
      page: "*.html",
      fonts: "assets/fonts/**",
      images: "assets/images/**",
    }
  }
}
try {
  let newConfig = require(`${cwd}/page.config.js`)
  config = Object.assign({}, config, newConfig)
} catch (error) {
}
// 自动加载各种依赖
const plugins = loadPlugins()
// 开启一个具有热更新的服务 但是修改html内容不会发生变化
const bs = browserSync.create()
const serve = () => {
  watch(config.build.paths.styles, { cwd: config.build.src }, style)
  watch(config.build.paths.script, { cwd: config.build.src }, script)
  watch(config.build.paths.page, { cwd: config.build.src }, page)
  watch([config.build.paths.fonts, config.build.paths.images ], { cwd: config.build.src },bs.reload)
  watch("**", { cwd: config.build.public }, bs.reload)
  return bs.init({
    notify: false,
    files: `${config.build.temp}/**`,
    server: {
      baseDir: [config.build.temp, config.build.src, config.build.public],
      routes: {
        "/node_modules": "node_modules"
      }
    },
  })
}
// src读取流 pipe到插件转换流  dest写入流
const style = () => {
  return src(config.build.paths.styles, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.sass({ outputStyle: 'expanded' }))
    .pipe(dest(config.build.temp))
}
const script = () => {
  return src(config.build.paths.script, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.babel({presets: [require('@babel/preset-env')]}))
    .pipe(dest(config.build.temp))
}
const page = () => {
  return src(config.build.paths.page, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.swig({data: config.data}))
    .pipe(dest(config.build.temp))
}
const compiler = parallel(page, script, style)
const image = () => {
  return src(config.build.paths.images, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}
const font = () => {
  return src(config.build.paths.fonts, { base: config.build.src, cwd: config.build.src })
    .pipe(plugins.imagemin())
    .pipe(dest(config.build.dist))
}
const clean = () => {
  return del([config.build.dist, config.build.temp])
}
const extra = () => {
  return src("**", { base: config.build.public, cwd: config.build.public })
    .pipe(dest(config.build.dist))
}
// useref 用来处理html中的一些第三方依赖 根据构建注释去把文件进行压缩生成到新的css/js文件
const useref = () => {
  return src(config.build.paths.page, {base: config.build.temp, cwd: config.build.temp})
    .pipe(plugins.useref({searchPath: [config.build.temp , "."]}))
    // 需要判断 js/html/css 分别使用不同插件去压缩
    .pipe(plugins.if(/\.js$/, plugins.uglify()))
    .pipe(plugins.if(/\.css$/, plugins.cleanCss()))
    .pipe(plugins.if(/\.html$/, plugins.htmlmin({
      collapseWhitespace: true,
      minifyCss: true,
      minifyJs: true
    })))
    .pipe(dest(config.build.dist))
}
const develop = series(clean, compiler, serve)
const build = series(clean, parallel(series(compiler, useref),extra, font, image))
module.exports = {
  build,
  clean,
  develop,
}